/*******************************************************************************
 * copyright (c) 2009 - 2010 Simon Allen
 *
 * This file is part of Convex Media Converter.
 *
 * Convex Media Converter is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * Convex Media Converter is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with Convex Media Converter; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ******************************************************************************/


#ifndef OUTPUTSETTINGS_H
#define OUTPUTSETTINGS_H

#include <QString>
#include <QStringList>
#include <QSettings>

using namespace std;


class OutputSettings
{
	private:
		QString presetName;
		QString format;
		bool audio;
		QString audioCodec;
		int audioBitrate;
		QString audioMode;
		int audioSampleRate;
		int audioChannels;
		bool video;
		QString videoCodec;
		int videoBitrate;
		int width;
		int height;
		QString aspect;
		float frameRate;
		QString cmdOptions;
		QString outputDir;
		QString extension;

	public:
		const static QString FORMAT_AUDIO;
		const static QString FORMAT_MPEGTS;
		const static QString FORMAT_MPEGPS;
		const static QString FORMAT_MPEG1;
		const static QString FORMAT_OGV;
		const static QString FORMAT_WMV;
		const static QString FORMAT_DVD;
		const static QString FORMAT_MJPEG;
		const static QString FORMAT_MKV;
		const static QString FORMAT_RAW;
		const static QString FORMAT_MPEG4;
		const static QString FORMAT_FLASH;
		const static QString FORMAT_AVI;

		const static QString FORMAT_AUDIO_DESC;
		const static QString FORMAT_MPEGTS_DESC;
		const static QString FORMAT_MPEGPS_DESC;
		const static QString FORMAT_MPEG1_DESC;
		const static QString FORMAT_OGV_DESC;
		const static QString FORMAT_WMV_DESC;
		const static QString FORMAT_DVD_DESC;
		const static QString FORMAT_MJPEG_DESC;
		const static QString FORMAT_MKV_DESC;
		const static QString FORMAT_RAW_DESC;
		const static QString FORMAT_MPEG4_DESC;
		const static QString FORMAT_FLASH_DESC;
		const static QString FORMAT_AVI_DESC;

		const static QString AUDIO_CODEC_MP2;
		const static QString AUDIO_CODEC_MP3;
		const static QString AUDIO_CODEC_AAC;
		const static QString AUDIO_CODEC_AC3;
		const static QString AUDIO_CODEC_VORBIS;
		const static QString AUDIO_CODEC_FLAC;
		const static QString AUDIO_CODEC_WAV;
		const static QString AUDIO_CODEC_WMAV1;
		const static QString AUDIO_CODEC_WMAV2;

		const static QString AUDIO_CODEC_MP2_DESC;
		const static QString AUDIO_CODEC_MP3_DESC;
		const static QString AUDIO_CODEC_AAC_DESC;
		const static QString AUDIO_CODEC_AC3_DESC;
		const static QString AUDIO_CODEC_VORBIS_DESC;
		const static QString AUDIO_CODEC_FLAC_DESC;
		const static QString AUDIO_CODEC_WAV_DESC;
		const static QString AUDIO_CODEC_WMAV1_DESC;
		const static QString AUDIO_CODEC_WMAV2_DESC;

		const static QString VIDEO_CODEC_MPEG1;
		const static QString VIDEO_CODEC_MPEG2;
		const static QString VIDEO_CODEC_XVID;
		const static QString VIDEO_CODEC_H264;
		const static QString VIDEO_CODEC_H263;
		const static QString VIDEO_CODEC_WMV1;
		const static QString VIDEO_CODEC_WMV2;
		const static QString VIDEO_CODEC_MJPEG;
		const static QString VIDEO_CODEC_THEORA;
		const static QString VIDEO_CODEC_DIRAC;

		const static QString VIDEO_CODEC_MPEG1_DESC;
		const static QString VIDEO_CODEC_MPEG2_DESC;
		const static QString VIDEO_CODEC_XVID_DESC;
		const static QString VIDEO_CODEC_H264_DESC;
		const static QString VIDEO_CODEC_H263_DESC;
		const static QString VIDEO_CODEC_WMV1_DESC;
		const static QString VIDEO_CODEC_WMV2_DESC;
		const static QString VIDEO_CODEC_MJPEG_DESC;
		const static QString VIDEO_CODEC_THEORA_DESC;
		const static QString VIDEO_CODEC_DIRAC_DESC;

		const static QString AUDIO_BITRATE_VERY_LOW;
		const static QString AUDIO_BITRATE_LOW;
		const static QString AUDIO_BITRATE_NORMAL;
		const static QString AUDIO_BITRATE_HIGH;
		const static QString AUDIO_BITRATE_VERY_HIGH;
		const static QString AUDIO_BITRATE_ULTRA_HIGH;

		const static QString AUDIO_BITRATE_VERY_LOW_DESC;
		const static QString AUDIO_BITRATE_LOW_DESC;
		const static QString AUDIO_BITRATE_NORMAL_DESC;
		const static QString AUDIO_BITRATE_HIGH_DESC;
		const static QString AUDIO_BITRATE_VERY_HIGH_DESC;
		const static QString AUDIO_BITRATE_ULTRA_HIGH_DESC;

		const static int AUDIO_MP3_VBR_LOW;
		const static int AUDIO_MP3_VBR_NORMAL;
		const static int AUDIO_MP3_VBR_HIGH;
		const static int AUDIO_MP3_VBR_VERY_HIGH;

		const static int AUDIO_VORBIS_VBR_VERY_LOW;
		const static int AUDIO_VORBIS_VBR_LOW;
		const static int AUDIO_VORBIS_VBR_NORMAL;
		const static int AUDIO_VORBIS_VBR_HIGH;
		const static int AUDIO_VORBIS_VBR_VERY_HIGH;
		const static int AUDIO_VORBIS_VBR_ULTRA_HIGH;

		const static int AUDIO_AAC_VBR_VERY_LOW;
		const static int AUDIO_AAC_VBR_LOW;
		const static int AUDIO_AAC_VBR_NORMAL;
		const static int AUDIO_AAC_VBR_HIGH;
		const static int AUDIO_AAC_VBR_VERY_HIGH;

		const static QString AUDIO_MODE_VBR;
		const static QString AUDIO_MODE_ABR;
		const static QString AUDIO_MODE_CBR;

		const static QString AUDIO_MODE_VBR_DESC;
		const static QString AUDIO_MODE_ABR_DESC;
		const static QString AUDIO_MODE_CBR_DESC;

		const static QString AUDIO_CHANNELS_1;
		const static QString AUDIO_CHANNELS_2;
		const static QString AUDIO_CHANNELS_4;
		const static QString AUDIO_CHANNELS_2_1;
		const static QString AUDIO_CHANNELS_4_1;
		const static QString AUDIO_CHANNELS_5_1;
		const static QString AUDIO_CHANNELS_6_1;
		const static QString AUDIO_CHANNELS_7_1;

		const static QString AUDIO_CHANNELS_1_DESC;
		const static QString AUDIO_CHANNELS_2_DESC;
		const static QString AUDIO_CHANNELS_4_DESC;
		const static QString AUDIO_CHANNELS_2_1_DESC;
		const static QString AUDIO_CHANNELS_4_1_DESC;
		const static QString AUDIO_CHANNELS_5_1_DESC;
		const static QString AUDIO_CHANNELS_6_1_DESC;
		const static QString AUDIO_CHANNELS_7_1_DESC;

		const static QString VIDEO_STANDARD_576P;
		const static QString VIDEO_STANDARD_480P;
		const static QString VIDEO_STANDARD_720P;
		const static QString VIDEO_STANDARD_1080P;
		const static QString VIDEO_STANDARD_QVGA;
		const static QString VIDEO_STANDARD_VGA;
		const static QString VIDEO_STANDARD_SVGA;
		const static QString VIDEO_STANDARD_XGA;
		const static QString VIDEO_STANDARD_CUSTOM;

		const static QString VIDEO_STANDARD_576P_DESC;
		const static QString VIDEO_STANDARD_480P_DESC;
		const static QString VIDEO_STANDARD_720P_DESC;
		const static QString VIDEO_STANDARD_1080P_DESC;
		const static QString VIDEO_STANDARD_QVGA_DESC;
		const static QString VIDEO_STANDARD_VGA_DESC;
		const static QString VIDEO_STANDARD_SVGA_DESC;
		const static QString VIDEO_STANDARD_XGA_DESC;
		const static QString VIDEO_STANDARD_CUSTOM_DESC;

		const static QString VIDEO_ASPECT_FULLSCREEN;
		const static QString VIDEO_ASPECT_WIDESCREEN;

		const static QString VIDEO_ASPECT_FULLSCREEN_DESC;
		const static QString VIDEO_ASPECT_WIDESCREEN_DESC;

		const static QString EXTENSION_TS;
		const static QString EXTENSION_MPG;
		const static QString EXTENSION_OGG;
		const static QString EXTENSION_WMV;
		const static QString EXTENSION_MJP;
		const static QString EXTENSION_MKV;
		const static QString EXTENSION_RAW;
		const static QString EXTENSION_MP4;
		const static QString EXTENSION_FLV;
		const static QString EXTENSION_AVI;

		const static QString EXTENSION_AUDIO_MP2;
		const static QString EXTENSION_AUDIO_MP3;
		const static QString EXTENSION_AUDIO_M4A;
		const static QString EXTENSION_AUDIO_AC3;
		const static QString EXTENSION_AUDIO_OGG;
		const static QString EXTENSION_AUDIO_FLAC;
		const static QString EXTENSION_AUDIO_WAV;
		const static QString EXTENSION_AUDIO_WMA;

		const static QStringList MP2_SAMPLE_RATES;
		const static QStringList MP3_SAMPLE_RATES;
		const static QStringList AAC_SAMPLE_RATES;
		const static QStringList AC3_SAMPLE_RATES;
		const static QStringList VORBIS_SAMPLE_RATES;
		const static QStringList FLAC_SAMPLE_RATES;
		const static QStringList WAV_SAMPLE_RATES;
		const static QStringList WMAV1_SAMPLE_RATES;
		const static QStringList WMAV2_SAMPLE_RATES;

		OutputSettings();
		void setPresetName(const QString newName) { presetName = newName; }
		QString getPresetName() const { return presetName; }
		void setFormat(const QString newFormat) { format = newFormat; }
		QString getFormat() const { return format; }
		void setAudioCodec(const QString newAudioCodec) { audioCodec = newAudioCodec; }
		QString getAudioCodec() const { return audioCodec; }
		void setAudioBitrate(const int newBitrate) { audioBitrate = newBitrate; }
		int getAudioBitrate() const { return audioBitrate; }
		void setAudioSampleRate(const int newRate) { audioSampleRate = newRate; }
		int getAudioSampleRate() const { return audioSampleRate; }
		void setAudioChannels(const int channels) { audioChannels = channels; }
		int getAudioChannels() const { return audioChannels; }
		void setAudioMode(const QString newMode) { audioMode = newMode; }
		QString getAudioMode() const { return audioMode; }
		void setAudio(const bool type) { audio = type; }
		bool hasAudio() const { return audio; }
		void setVideo(const bool type) { video = type; }
		bool hasVideo() const { return video; }
		void setVideoCodec(const QString newCodec) { videoCodec = newCodec; }
		QString getVideoCodec() const { return videoCodec; }
		void setVideoBitrate(const int newBitrate) { videoBitrate = newBitrate; }
		int getVideoBitrate() const { return videoBitrate; }
		void setWidth(const int newWidth) { width = newWidth; }
		int getWidth() const { return width; }
		void setHeight(const int newHeight) { height = newHeight; }
		int getHeight() const { return height; }
		void setAspect(const QString newAspect) { aspect = newAspect; }
		QString getAspect() const { return aspect; }
		void setFrameRate(const float newRate) { frameRate = newRate; }
		float getFrameRate() const { return frameRate; }
		void setOutputDir(const QString newDir) { outputDir = newDir; }
		QString getOutputDir() const { return outputDir; }
		void setExtension(const QString newExt) { extension = newExt; }
		QString getExtension() const { return extension; }
		QString getCmdOptions() const
		{ return cmdOptions; }
		void setCmdOptions(const QString newOptions)
		{ cmdOptions = newOptions; }
		void clearCmdOptions() { cmdOptions.clear(); }
};

class PresetSettings: public QSettings
{
	private:
		QList<QPair<QString, QString> > formatPairs;
		QList<QPair<QString, QString> > audioCodecPairs;
		QList<QPair<QString, QString> > videoCodecPairs;
		QList<QPair<QString, QString> > audioBitratePairs;
		QList<QPair<QString, QString> > audioModePairs;
		QList<QPair<QString, QString> > audioChannelPairs;
		QList<QPair<QString, QString> > videoStandardPairs;
		QList<QPair<QString, QString> > videoAspectPairs;

		void createFormatPairs();
		void createAudioCodecPairs();
		void createVideoCodecPairs();
		void createAudioBitratePairs();
		void createAudioModePairs();
		void createAudioChannelsPairs();
		void createVideoStandardPairs();
		void createVideoAspectPairs();
		void writeDefaultPresets();


	public:
		const static QString KEY_FORMAT;
		const static QString KEY_AUDIO_STREAM;
		const static QString KEY_VIDEO_STREAM;
		const static QString KEY_CODEC;
		const static QString KEY_BITRATE;
		const static QString KEY_MODE;
		const static QString KEY_SAMPLE_RATE;
		const static QString KEY_CHANNELS;
		const static QString KEY_STANDARD;
		const static QString KEY_WIDTH;
		const static QString KEY_HEIGHT;
		const static QString KEY_ASPECT;
		const static QString KEY_FRAME_RATE;
		const static QString KEY_CMD_OPTIONS;
		const static QString KEY_EXTENSION;

		PresetSettings(const QSettings::Scope scope,
			       const QString &organization,
			       const QString &application = QString(),
			       QObject *pointer = 0);

		enum PAIR_TYPE {FORMAT, AUDIO_CODEC, VIDEO_CODEC,
				     AUDIO_BITRATE, AUDIO_MODE,
				     AUDIO_CHANNELS, VIDEO_STANDARD,
				     VIDEO_ASPECT};

		QString getMatch(const QString key, const PAIR_TYPE type) const;
		QList<QPair<QString, QString> > getPairs(const PAIR_TYPE type) const;
};

#endif // OUTPUTSETTINGS_H
